/**
 * @name 事件总线
 * @author Conan
 * @variation 1.0
 * 
 * enevtList: {
 *    // 事件名称
 *    enevtName: [ fun1, fun2 ]
 * }
 * 
 * broadcastList: {
 *  // 频道名称
 *  channelName: {
 *    // 某个订阅者名称
 *    subscriber: {
 *      // 某个订阅者拥有的事件
 *      enevts: []
 *    }
 *  } 
 * }
 */


class EventBus {
  constructor() {
    // 事件队列, 用来存储注册的所有事件
    this.enevtList = {}
    // 发布者队列, 用来存储对应事件的发布者 --- 暂未开发
    this.publisherList = {}

    // 广播队列, 用来存储已组为单位的广播(多个频道)
    this.broadcastList = {}
  }

  // -------------------------------------------- 事件订阅 start
  /**
   * 事件订阅
   * @param {*} name 事件名称
   * @param {*} fun 事件回调
   */
  on(name, fun) {
    // 添加订阅事件的任务
    this._AddTask(name, fun)
  }
  
  /**
   * 发布订阅(发送数据)
   * @param {*} name 事件名称
   * @param  {...any} args 发布订阅的参数, 可多个
   */
  emit(name, ...args) {
    // 获取该事件名称注册的任务回调
    const task = this._GetTask(name)
    if (task) {
      task.forEach(fun => {
        fun(...args)
      })
    }
  }

  /**
   * 取消订阅
   * @param {*} name 事件名称
   */
  off(name) {
    // 获取该事件名称注册的任务回调
    const task = this._GetTask(name)
    if (task) {
      this._DelTask(name)
    }
  }

  /**
   * 添加订阅的任务
   * @param {*} name 
   */
  _AddTask(name, fun) {
    // 获取该事件名称注册的任务回调
    const task = this._GetTask(name)
    if (task) {
      this.enevtList[name].push(fun)
    } else {
      this.enevtList[name] = [fun]
    }
  }

  /**
   * 获取某订阅的任务
   * @param {*} name 事件名称
   * @returns 该事件的任务
   */
  _GetTask(name) {
    return this.enevtList[name]
  }
  
  /**
   * 删除某订阅的任务
   * @param {*} name 事件名称
   */
   _DelTask(name) {
    delete this.enevtList[name]
  }
  // -------------------------------------------- 事件订阅 end


  
  // -------------------------------------------- 广播 start
  /**
   * 创建一个广播频道(一个组)
   * @param {*} name 
   */
  createChannel(name) {
    // 获取某个频道
    const channel = this.broadcastList[name]

    // 如没有该频道则新增一个频道
    if (!channel) {
      this.broadcastList[name] = this._CreateChannelTemplate()
    }
  }

  /**
   * 频道广播
   * @param {*} channelName 频道名称
   * @param {*} value 广播数据
   */
  channelEmit(channelName, ...args) {
    // 获取某个频道
    const channel = this.broadcastList[channelName]
    if (channel) {
      for (let key in channel.subscriber) {
        channel.subscriber[key].enevts.forEach(fun => {
          fun(...args)
        })
      }
    }
  }

  /**
   * 频道订阅
   * @param {*} channelName 频道名称
   * @param {*} name 订阅者名称
   * @param {*} fun 订阅者回调事件
   */
  channelOn(channelName, name, fun) {
    // 获取某个频道
    const channel = this.broadcastList[channelName]
    if (channel) {
      // 获取该频道里某个订阅者
      const subscriber = channel.subscriber[name]
      if (subscriber) { // 存在订阅者
        this.broadcastList[channelName].subscriber[name].enevts.push(fun)
      } else { // 不存在订阅者
        this.broadcastList[channelName].subscriber[name] = this._CreateSubscriberTemplate()
        this.broadcastList[channelName].subscriber[name].enevts.push(fun) 
      }
    }
  }

  /**
   * 取消频道
   * @param {*} channelName 
   */
  channeOff(channelName) {
    // 获取某个频道
    const channel = this.broadcastList[channelName]
    if (channel) {
      delete this.broadcastList[channelName]
    }
  }
  
  /**
   * 创建一个频道对象模板
   * @returns 返回频道对象
   */
  _CreateChannelTemplate() {
    return {
      // 该频道的一些设置
      setting: {},
      // 该频道的订阅者
      subscriber: {} 
    }
  }

  /**
   * 创建某个频道下的订阅者对象模板
   * @returns 
   */
  _CreateSubscriberTemplate() {
    return {
      // 订阅者事件队列
      enevts: [],
      // 订阅者配置
      setting: {}
    }
  }
  // -------------------------------------------- 广播 end



}